package com.alingrad.iou;

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Calendar;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.Dialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.format.DateFormat;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.FilterQueryProvider;
import android.widget.SimpleCursorAdapter;
import android.widget.SimpleCursorAdapter.CursorToStringConverter;
import android.widget.Toast;
import android.widget.ToggleButton;

public class NewTransactionActivity extends Activity {
	public static final String ACTION_NEW = "_new";
	public static final String ACTION_EDIT = "_edit";
	public static final String ACTION_NEW_WITH_PERSON = "_new_person";
	
	private EditText mDateEditor;
	private AutoCompleteTextView mPersonEditor;
	private EditText mAmountEditor;
	private ToggleButton mIOweYouButton;
	
	private Button mAcceptButton;
	private Button mCancelButton;
	
	private NumberFormat mCurrencyFormat;
	
	public static final String KEY_ID = "_id";
	public static final String KEY_PERSON_ID = "personId";
	private static final String KEY_AMOUNT = "amount";
	private long mId;
	private long mPersonId;
	private long mContactId;
	private float mAmount;
	
	private ContentResolver mCr;
	
	private static final int DIALOG_DATE_ID = 0;
	private static final int DIALOG_ERROR_FIELDS_ID = 1;
	
	private DatePickerDialog mDialog;
	
	private IOUDbAdapter mDbAdapter;
	
	private String mIntentAction;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.new_transaction);
		mCr = getContentResolver();
		mId = -1;
		mPersonId = -1;
		mContactId = -1;
		mAmount = -1;
		
		mIntentAction = getIntent().getAction();
		if (mIntentAction.equals(ACTION_EDIT))
			mId = getIntent().getLongExtra(KEY_ID, -1);
		
		if (mIntentAction.equals(ACTION_NEW_WITH_PERSON))
			mPersonId = getIntent().getLongExtra(KEY_PERSON_ID, -1);
		
		if (savedInstanceState != null) {
			mId = savedInstanceState.getLong(KEY_ID, -1);
			mPersonId = savedInstanceState.getLong(KEY_PERSON_ID, -1);
			mAmount = savedInstanceState.getFloat(KEY_AMOUNT, -1);
		}
		
		final View.OnClickListener clickListener = new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if (v == mDateEditor)
					onDateEditorClicked();
				else if (v == mAcceptButton)
					onAcceptButtonClicked();
				else if (v == mCancelButton)
					onCancelButtonClicked();
			}
		};
		
		Calendar c = Calendar.getInstance();
		mDateEditor = (EditText)findViewById(R.id.new_transaction_date);
		mDateEditor.setText(DateFormat.format("yyyy-MM-dd", c));
		mDateEditor.setOnClickListener(clickListener);
		mDialog = new DatePickerDialog(this, 
				new OnDateSetListener() {
					@Override
					public void onDateSet(DatePicker view, int year, int monthOfYear,
							int dayOfMonth) {
						mDateEditor.setText(year + "-" + (monthOfYear + 1) + "-" + dayOfMonth);
					}
				}, c.get(Calendar.YEAR),
				c.get(Calendar.MONTH),
				c.get(Calendar.DAY_OF_MONTH));

		
		mPersonEditor = (AutoCompleteTextView)findViewById(R.id.new_transaction_contact);
		mPersonEditor.setAdapter(getContactAdapter());
		mPersonEditor.addTextChangedListener(new TextWatcher() {
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				mPersonId = -1;
				mContactId = -1;
			}
			
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}
			
			@Override
			public void afterTextChanged(Editable s) {
			}
		});
		mPersonEditor.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position,
					long id) {
				mContactId = id;
				mPersonId = -1;
			}
		});
		
		
		mAmountEditor = (EditText)findViewById(R.id.new_transaction_amount);
		mCurrencyFormat = NumberFormat.getCurrencyInstance();
		mAmountEditor.setOnFocusChangeListener(new OnFocusChangeListener() {
			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				if (hasFocus) {
					try {
						mAmountEditor.setText(
								"" + mCurrencyFormat.parse(mAmountEditor.getText().toString()).floatValue());
					} catch (ParseException e) {
					}
				}
				else {
					try {
						float amount = Float.parseFloat(mAmountEditor.getText().toString());
						mAmountEditor.setText(mCurrencyFormat.format(amount));
						mAmount = (int)(amount * 100) / 100f; 
					} catch (NumberFormatException ex) {
						mAmount = -1;
						mAmountEditor.setText("");
					}
				}
						
			}
		});
		
		
		mIOweYouButton = (ToggleButton)findViewById(R.id.new_transaction_ioweyou);
		
		
		mAcceptButton = (Button)findViewById(R.id.new_transaction_accept);
		mAcceptButton.setOnClickListener(clickListener);
		
		
		mCancelButton = (Button)findViewById(R.id.new_transaction_cancel);
		mCancelButton.setOnClickListener(clickListener);
			
		mDbAdapter = new IOUDbAdapter(this);
		
		mPersonEditor.requestFocus();
	}
	
	private SimpleCursorAdapter getContactAdapter() {
		Cursor c = mCr.query(ContactsContract.Contacts.CONTENT_URI, 
				new String[] {Contacts.DISPLAY_NAME, Contacts._ID}, null, null, null);
		final SimpleCursorAdapter retval = new SimpleCursorAdapter(this, android.R.layout.simple_dropdown_item_1line, c, new String[] {
				Contacts.DISPLAY_NAME}, new int[] {android.R.id.text1});
		retval.setCursorToStringConverter(new CursorToStringConverter() {
			@Override
			public CharSequence convertToString(Cursor cursor) {
				return cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME));
			}
		});
		retval.setFilterQueryProvider(new FilterQueryProvider() {
			@Override
			public Cursor runQuery(CharSequence constraint) {
				return mCr.query(Contacts.CONTENT_URI, 
						new String[] { Contacts.DISPLAY_NAME, 
						Contacts._ID}, 
						Contacts.DISPLAY_NAME + " LIKE '%" + constraint + "%'", 
						null, 
						null);
			}
		});
		return retval;
	}
	
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putLong(KEY_ID, mId);
		outState.putLong(KEY_PERSON_ID, mPersonId);
		outState.putFloat(KEY_AMOUNT, mAmount);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		mDbAdapter.open();
		if (mIntentAction.equals(ACTION_EDIT))
			fillDataEdit();
		else if (mIntentAction.equals(ACTION_NEW_WITH_PERSON))
			fillDataNewWithPerson();
	}
	
	private void fillDataNewWithPerson() {
		Cursor c = mDbAdapter.getPerson(mPersonId);
		c.moveToFirst();
		mPersonEditor.setText(c.getString(
				c.getColumnIndex(IOUDbAdapter.KEY_PEOPLE_NAME)));
		c.close();
		mAmountEditor.requestFocus();
	}
	
	private void fillDataEdit() {
		Cursor c = mDbAdapter.getTransaction(mId);
		startManagingCursor(c);
		c.moveToFirst();
		final String date = c.getString(c.getColumnIndex(
				IOUDbAdapter.KEY_TRANSACTION_DATE));
		mDateEditor.setText(date);
		mPersonId = c.getLong(c.getColumnIndex(
				IOUDbAdapter.KEY_TRANSACTION_PERSON_ID));
		Cursor person = mDbAdapter.getPerson(mPersonId);
		person.moveToFirst();
		long contactId = person.getLong(person.getColumnIndex(
				IOUDbAdapter.KEY_PEOPLE_CONTACT_ID));
		if (contactId != -1) {
			Cursor contact = mCr.query(ContactsContract.Contacts.CONTENT_URI,
					new String[] {ContactsContract.Contacts.DISPLAY_NAME},
					ContactsContract.Contacts._ID + " = " + contactId, null, null);
			contact.moveToFirst();
			mPersonEditor.setText(contact.getString(contact.getColumnIndex(
					ContactsContract.Contacts.DISPLAY_NAME)));
			contact.close();
		} else {
			mPersonEditor.setText(person.getString(person.getColumnIndex(
					IOUDbAdapter.KEY_PEOPLE_NAME)));
		}
		person.close();
		mAmount = c.getFloat(c.getColumnIndex(
				IOUDbAdapter.KEY_TRANSACTION_AMOUNT));
		if (mAmount < 0)
			mAmount *= -1;
		else
			mIOweYouButton.setChecked(true);
		mAmountEditor.setText("" + mAmount);
		mAmountEditor.clearFocus();
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		switch(id) {
		case DIALOG_DATE_ID:
			return mDialog;
		case DIALOG_ERROR_FIELDS_ID:
			AlertDialog.Builder b = new AlertDialog.Builder(this);
			AlertDialog d = b.create();
			d.setTitle(R.string.error_dialog_label);
			d.setMessage(getResources().getString(R.string.error_new_transaction_fields_message));
			d.setButton(getResources().getString(R.string.okay), new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
				}
			});
			return d;
		}
		return super.onCreateDialog(id);
	}
	
	private void onDateEditorClicked() {
		showDialog(DIALOG_DATE_ID);
	}
	
	private void onAcceptButtonClicked() {
		getCurrentFocus().clearFocus();
		if (mAmount == -1 || (mPersonId == -1 && mPersonEditor.getText().equals("")))
			showDialog(DIALOG_ERROR_FIELDS_ID);
		else {
			if (!mIOweYouButton.isChecked())
				mAmount *= -1;
			if (mPersonId == -1) {
				if (mContactId == -1) {
					mPersonId = mDbAdapter.getPersonIdFromName(mPersonEditor.getText().toString());
					if (mPersonId == -1)
						mPersonId = mDbAdapter.createPerson(mContactId, mPersonEditor.getText().toString());
				}
				else {
					mPersonId = mDbAdapter.getPersonIdFromContact(mContactId);
					if (mPersonId == -1)
						mPersonId = mDbAdapter.createPerson(mContactId);
				}
			}
			if (mIntentAction.equals(ACTION_NEW) || mIntentAction.equals(ACTION_NEW_WITH_PERSON)) {
					mDbAdapter.addTransaction(mPersonId, mDateEditor.getText().toString(), mAmount);
					Toast.makeText(this, R.string.toast_new_transaction_complete, Toast.LENGTH_SHORT).show();
			}
			else if (mIntentAction.equals(ACTION_EDIT)) {
					mDbAdapter.updateTransaction(mId, mPersonId, mDateEditor.getText().toString(), mAmount);
					Toast.makeText(this, R.string.toast_new_transaction_changed, Toast.LENGTH_SHORT).show();
			}
			finish();
		}
	}
	
	private void onCancelButtonClicked() {
		finish();
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		mDbAdapter.close();
	}
}
